package com.hsav.kcxb.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.hsav.kcxb.R;
import com.hsav.kcxb.utils.LrcEntry;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by LiB on 2017/6/29.
 */

public class MusicClipView extends View {
    static class Handler
    {
        private final float textWidth;
        private final int textHeight;
        RectF rect;
        RectF thumbBGRect;
        String name;
        Paint paintForThumbBG;
        Paint paintForThumbText;
        private Paint paintForLine;
        private float textAscent;
        private Context context;

        Handler(Context context, String name, float x, float y, float width, float height)
        {
            this.context = context;
            this.name = name;
            rect = new RectF(x, y, x + width, y + height);

            paintForLine = new Paint();
            paintForLine.setAntiAlias(true);

            paintForThumbBG = new Paint();
            paintForThumbBG.setAntiAlias(true);
            paintForThumbBG.setStyle(Paint.Style.FILL);
            paintForThumbBG.setColor(context.getResources().getColor(R.color.colorAccent));

            paintForThumbText = new Paint();
            paintForThumbText.setAntiAlias(true);
            paintForThumbText.setTextSize(50);

            textWidth = paintForThumbText.measureText(name);
            Paint.FontMetrics fontMetrics = paintForThumbText.getFontMetrics();
            textAscent = fontMetrics.ascent;
            textHeight = (int)(Math.ceil(fontMetrics.descent - fontMetrics.ascent) + 2);
        }

        void setLocation(float x, float y)
        {
            float w = rect.width();
            float h = rect.height();
            rect.left = x;
            rect.top = y;
            rect.right = x + w;
            rect.bottom = y + h;
        }

        PointF getLocation()
        {
            return new PointF(rect.left, rect.top);
        }

        float width()
        {
            return rect.width();
        }

        float height()
        {
            return rect.height();
        }

        boolean hitTest(float x, float y)
        {
            return rect.contains(x, y);
        }

        void onDraw(Canvas canvas)
        {
            float halfHeight = height() / 2;
            canvas.drawRoundRect(thumbBGRect, halfHeight, halfHeight, paintForThumbBG);
            canvas.drawLine(thumbBGRect.width(), halfHeight, width(), halfHeight, paintForLine);
            canvas.drawText(name, thumbBGRect.left + 16, thumbBGRect.top + 16 - textAscent, paintForThumbText);
        }
    }

    private static final String TAG = MusicClipView.class.getName();
    private List<LrcEntry> lrcEntries;
    private List<Rect> lrcEntryBounds;
    private float offsetY;
    private Paint paintForLrc;
    private Paint paintForThumbBg;
    private Paint paintForThumbText;
    private Paint paintForLine;
    private float lastY;
    private int lrcTextAscent;
    private int lrcTextHeight;
    private int thumbTextAscent;
    private int thumbTextHeight;
    private int leading = 30;
    private int textAreaHeight;
    private float startHandlerLineY = 100;
    private float endHandlerLineY = 200;
    private float handlerLineWidth;
    private RectF startHandlerRect;
    private RectF endHandlerRect;

    private long startTime;
    private long endTime;
    private long totalTime;
    private boolean needCalcPosition;
    private Rect startTextBound = new Rect();
    private Rect endTextBound = new Rect();
    private RectF startThumbBgRect = new RectF();
    private RectF endThumbBgRect = new RectF();
    private float thumbRadius;
    private float startTextX;
    private float startTextY;
    private float startHandlerLineStartX;
    private float startHandlerLineEndX;
    private float endTextX;
    private float endTextY;
    private float endHandlerLineStartX;
    private float endHandlerLineEndX;
    private boolean isDraggingHandler;

    public MusicClipView(Context context) {
        super(context);
        init();
    }

    public MusicClipView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public long getStartTime()
    {
        return startTime;
    }

    public void setStartTime(long startTime)
    {
        this.startTime = startTime;
        needCalcPosition = true;
        postInvalidate();
    }

    public long getEndTime()
    {
        return endTime;
    }

    public void setEndTime(long endTime)
    {
        this.endTime = endTime;
        needCalcPosition = true;
        postInvalidate();
    }

    private void init() {
        paintForLrc = new Paint();
        paintForLrc.setAntiAlias(true);
        paintForLrc.setTextSize(50);
        Paint.FontMetricsInt fontMetrics = paintForLrc.getFontMetricsInt();
        lrcTextAscent = fontMetrics.ascent;
        lrcTextHeight = (int)(Math.ceil(fontMetrics.descent - fontMetrics.ascent) + 2);

        paintForThumbBg = new Paint();
        paintForThumbBg.setAntiAlias(true);
        paintForThumbBg.setStyle(Paint.Style.FILL);
        paintForThumbBg.setColor(getResources().getColor(R.color.colorAccent));

        paintForLine = new Paint();
        paintForLine.setAntiAlias(true);

        paintForThumbText = new Paint();
        paintForThumbText.setAntiAlias(true);
        paintForThumbText.setTextSize(50);
        paintForThumbText.setColor(getResources().getColor(R.color.color_white_normal));
        paintForThumbText.getTextBounds("开始", 0, 2, startTextBound);
        paintForThumbText.getTextBounds("结束", 0, 2, endTextBound);
        fontMetrics = paintForLrc.getFontMetricsInt();
        thumbTextAscent = fontMetrics.ascent;
        thumbTextHeight = (int)(Math.ceil(fontMetrics.descent - fontMetrics.ascent) + 2);

        needCalcPosition = true;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        startHandlerRect = new RectF(0, 0, getMeasuredWidth(), thumbTextHeight + 16 * 2);
        startThumbBgRect = new RectF(0, startHandlerRect.top, 16 * 2 + startTextBound.width(), startThumbBgRect.top + thumbTextHeight + 16 * 2);
        startTextX = startThumbBgRect.left + 16;
        startTextY = startThumbBgRect.top + 16 - thumbTextAscent;
        startHandlerLineStartX = startThumbBgRect.right;
        startHandlerLineEndX = getMeasuredWidth();
        startHandlerLineY = startThumbBgRect.height() / 2;

        endHandlerRect = new RectF(0, startHandlerRect.bottom, getMeasuredWidth(), startHandlerRect.bottom + thumbTextHeight + 16 * 2);
        endThumbBgRect = new RectF(getMeasuredWidth() - endTextBound.width() - 16 * 2, endHandlerRect.top, getMeasuredWidth(), endHandlerRect.top + thumbTextHeight + 16 * 2);
        endTextX = endThumbBgRect.left + 16;
        endTextY = endThumbBgRect.top + 16 - thumbTextAscent;
        endHandlerLineStartX = 0;
        endHandlerLineEndX = endThumbBgRect.left;
        endHandlerLineY = endHandlerRect.top + endHandlerRect.height() / 2;

        thumbRadius = startThumbBgRect.height() / 2;
    }

    public void loadLrc(final File lrcFile) {
        lrcEntries = LrcEntry.parseLrc(lrcFile);
        if (lrcEntries.size() == 0) return;
        totalTime = lrcEntries.get(lrcEntries.size() - 1).getTime();
        startTime = 0;
        endTime = totalTime;

        lrcEntryBounds = new ArrayList<>(lrcEntries.size());
        int height = 0;
        for (int i = 0; i < lrcEntries.size(); i++)
        {
            String text = lrcEntries.get(i).getText();
            Rect bound = new Rect();
            paintForLrc.getTextBounds(text, 0, text.length(), bound);
            lrcEntryBounds.add(bound);
            height += lrcTextHeight;
            if (i != lrcEntries.size() - 1)
                height += leading;
        }
        textAreaHeight = height;
        needCalcPosition = true;
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (needCalcPosition)
            calcPosition();

        canvas.translate(0, offsetY);
        if (lrcEntries != null)
        {
            for (int i = 0; i < lrcEntries.size(); i++)
            {
                String text = lrcEntries.get(i).getText();
                Rect bounds = lrcEntryBounds.get(i);
                int y = i * (lrcTextHeight + leading) - lrcTextAscent;
//            if (y < 0 || y > getHeight()) continue;
                canvas.drawText(text, (getMeasuredWidth() - bounds.width()) / 2, y, paintForLrc);
            }
        }

        canvas.drawRoundRect(startThumbBgRect, thumbRadius, thumbRadius, paintForThumbBg);
        canvas.drawRoundRect(endThumbBgRect, thumbRadius, thumbRadius, paintForThumbBg);
        canvas.drawLine(startHandlerLineStartX, startHandlerLineY, startHandlerLineEndX, startHandlerLineY, paintForLine);
        canvas.drawLine(endHandlerLineStartX, endHandlerLineY, endHandlerLineEndX, endHandlerLineY, paintForLine);
        canvas.drawText("结束", endTextX, endTextY, paintForThumbText);
        canvas.drawText("开始", startTextX, startTextY, paintForThumbText);
    }

    private void calcPosition() {

        startHandlerRect.top = startHandlerLineY - thumbTextHeight / 2 - 16;
        startHandlerRect.bottom = startHandlerLineY + thumbTextHeight / 2 + 16;
        startThumbBgRect.top = startHandlerRect.top;
        startThumbBgRect.bottom = startHandlerRect.bottom;
        startTextY = startThumbBgRect.top + 16 - thumbTextAscent;

        endHandlerRect.top = endHandlerLineY - thumbTextHeight / 2 - 16;
        endHandlerRect.bottom = endHandlerLineY + thumbTextHeight / 2 + 16;
        endThumbBgRect.top = endHandlerRect.top;
        endThumbBgRect.bottom = endHandlerRect.bottom;
        endTextY = endThumbBgRect.top + 16 - thumbTextAscent;

        needCalcPosition = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float currentX = event.getX();
        float currentY = event.getY();
        float deltaY = 0;
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                lastY = event.getY();
                if (startHandlerRect.contains(currentX, currentY) || startHandlerRect.contains(currentX, currentY))
                {
                    isDraggingHandler = true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                deltaY = currentY - lastY;
                if (isDraggingHandler)
                {
                    if (startHandlerRect.contains(currentX, currentY))
                        startHandlerLineY += deltaY;
                    else if (startHandlerRect.contains(currentX, currentY))
                        endHandlerLineY += deltaY;
                    needCalcPosition = true;
                }
                else
                {
                    offsetY += deltaY;
                }
                lastY = currentY;
                break;
            case MotionEvent.ACTION_CANCEL:
                if (isDraggingHandler)
                    isDraggingHandler = false;
                break;
        }
        offsetY = Math.max(Math.min(offsetY, 0), getMeasuredHeight() - textAreaHeight);
        postInvalidate();
        Log.d(TAG, String.format("lastY: %s, currentY: %s, deltaY: %s, offsetY: %s", lastY, currentY, deltaY, offsetY));
        return true;
    }
}
